﻿// // ******************************************************************
// //       /\ /|       @file       JellyfinQueryHandler.cs
// //       \ V/        @brief      await29
// //       | "")       @author     Await, 285283010@qq.com
// //       /  |
// //      /  \\        @Modified   2024-11-17 10:11
// //    *(__\_\        @Copyright  Copyright (c) , 2024-11-10 10:11 Await
// // ******************************************************************

using AutomaticSubtitles.Service.Application.Config.Commands;
using AutomaticSubtitles.Service.Domain.Config;
using AutomaticSubtitles.Service.Application.Jellyfin;
using AutomaticSubtitles.Service.Application.Jellyfin.Queries;
using Microsoft.AspNetCore.Mvc;

namespace AutomaticSubtitles.Service.Application.Jellyfin;

public class JellyfinQueryHandler(IConfigDataRepository repository, IHttpClientFactory httpClientFactory) : BaseAutoService
{
    [EventHandler]
    public async Task Handle(GetJellyfinItemsQuery query)
    {
        var autoConfig = await repository.FindAsync(x => x.Id == query.id);
        IsDataNotExist(autoConfig);
        var autoConfigUserId = autoConfig.UserId;
        if (autoConfigUserId.IsNullOrWhiteSpace())
        {
            var commd = new UpdateConfigTokenCommand(autoConfig.Id);
            await PublishAsync(commd);
            autoConfigUserId = commd.Result;
        }

        IsDataNotExist(autoConfigUserId);
        var jellyfinItemsDto = await JellyfinHelper.GetItems(httpClientFactory, autoConfig.Token, autoConfigUserId, autoConfig.ServerUrl);
        query.Result = jellyfinItemsDto;
    }

    [EventHandler]
    public async Task Handle(GetJellyfinItemDetailQuery query)
    {
        var autoConfig = await repository.FindAsync(x => x.Id == query.id);
        IsDataNotExist(autoConfig);
        var autoConfigUserId = autoConfig.UserId;
        if (autoConfigUserId.IsNullOrWhiteSpace())
        {
            var commd = new UpdateConfigTokenCommand(autoConfig.Id);
            await PublishAsync(commd);
            autoConfigUserId = commd.Result;
        }

        IsDataNotExist(autoConfigUserId);
        var jellyfinItemDetailDto = await JellyfinHelper.GetItemDetail(httpClientFactory, autoConfig.Token, query.id.ToString(), autoConfig.ServerUrl);
        query.Result = jellyfinItemDetailDto;
    }

    [EventHandler]
    public async Task Handle(GetJellyfinStreamQuery query)
    {
        var autoConfig = await repository.FindAsync(x => x.Id == query.id);
        IsDataNotExist(autoConfig);
        var autoConfigUserId = autoConfig.UserId;
        if (autoConfigUserId.IsNullOrWhiteSpace())
        {
            var commd = new UpdateConfigTokenCommand(autoConfig.Id);
            await PublishAsync(commd);
            autoConfigUserId = commd.Result;
        }

        IsDataNotExist(autoConfigUserId);
        var stream = await JellyfinHelper.GetStream(httpClientFactory, autoConfig.Token, query.id.ToString(), autoConfig.ServerUrl);
        query.Result = new FileStreamResult(stream, "video/mp4");
    }

    [EventHandler]
    public async Task Handle(GetJellyfinChildrenQuery query)
    {
        var autoConfig = await repository.FindAsync(x => x.Id == query.id);
        IsDataNotExist(autoConfig);
        var autoConfigUserId = autoConfig.UserId;
        if (autoConfigUserId.IsNullOrWhiteSpace())
        {
            var commd = new UpdateConfigTokenCommand(autoConfig.Id);
            await PublishAsync(commd);
            autoConfigUserId = commd.Result;
        }

        IsDataNotExist(autoConfigUserId);
        var jellyfinItemsDto = await JellyfinHelper.GetChildren(httpClientFactory, autoConfig.Token, query.id.ToString(), autoConfig.ServerUrl);
        query.Result = jellyfinItemsDto;
    }

    [EventHandler]
    public async Task Handle(GetJellyfinImageQuery query)
    {
        var autoConfig = await repository.FindAsync(x => x.Id == query.id);
        IsDataNotExist(autoConfig);

        var client = httpClientFactory.CreateClient();
        client.DefaultRequestHeaders.Add("X-MediaBrowser-Token", autoConfig.Token);
        var response = await client.GetAsync($"{autoConfig.ServerUrl}/Items/{query.itemId}/Images/{query.imageType}");
        response.EnsureSuccessStatusCode();

        query.Result = await response.Content.ReadAsByteArrayAsync();
    }
}